package com.newsproject.service.impl;

import Util.FormatTime;
import Util.ValidationUtil;

import cn.hutool.core.bean.BeanUtil;
import com.newsproject.mapper.NewsMapper;
import com.newsproject.mapper.UserMapper;
import com.newsproject.pojo.DTO.AccountUser;
import com.newsproject.pojo.DTO.PostDTO;
import com.newsproject.pojo.HotSearch;
import com.newsproject.pojo.Result;
import com.newsproject.pojo.User;
import com.newsproject.pojo.vo.UserVo;
import com.newsproject.service.MinioService;
import com.newsproject.service.UserService;
import com.newsproject.service.VerificationCodeService;

import lombok.extern.slf4j.Slf4j;

import net.bytebuddy.utility.RandomString;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private VerificationCodeService verificationCodeService;
    @Autowired
    private NewsMapper newsMapper;
    @Autowired
    private MinioService minioService;

    @Override
    public ModelAndView login(String email, String password, HttpSession session) {
        ModelAndView mv = new ModelAndView();
        Map<String, Object> param = new HashMap<>();
        param.put("email", email);
        AccountUser account =  userMapper.findUserByEmailOrUserId(param);
        User user = new User();
        BeanUtil.copyProperties(account,user);
        session.setAttribute("account", account);
        log.info("用户{}登陆",user.toString());
        if(account==null){
            mv.addObject("message","该邮箱未被注册");
            mv.setViewName("login");
            return mv;
        }
         //判断密码是否正确
        if( !passwordEncoder.matches(password, account.getPassWord()) ){
            mv.addObject("message","邮箱或密码错误");
            mv.setViewName("login");
            return mv;
        }else{
            //判断用户是否被封禁
            if(account.getAccountStatus()==1){
                mv.addObject("message","该用户已被封禁");
                mv.setViewName("login");
                return mv;
            }
            session.setAttribute("userInfo",user);
            mv.addObject("userInfo",account);
            mv.addObject("message","登陆成功");
            log.info("用户{}登陆成功",account.getAdminStatus());
            if(account.getAdminStatus()==1){
                mv.setViewName("redirect:/AdminController/users");
            }else{
                mv.setViewName("redirect:/user/recommendPage");
            }
        }
        return mv;
    }


    @Override
    public ModelAndView register(String email,String code  ,String password ,HttpSession session ) {
        //根据email查询用户id，判断email是否已经被使用
        Integer user_id = userMapper.selectUserIdByEmail(email);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("email",email);
        modelAndView.addObject("password",password);
        modelAndView.addObject("code",code);
        //如果email已被注册的情况
        if(user_id !=null){
           modelAndView.addObject("message","该邮箱已被注册");
           modelAndView.setViewName("register");
           return modelAndView;
        }
        //email没有被注册，判断email和password是否符合格式要求
        if( ! ValidationUtil.isValidEmail(email) || ! ValidationUtil.isValidPassword(password)){
            modelAndView.addObject("message","邮箱或密码格式错误");
            modelAndView.setViewName("register");
            return modelAndView;
        }
        //上述条件都符合，判断验证码是否正确
        if(!verificationCodeService.verifyVerificationCode(session,code)){
            modelAndView.addObject("message","验证码错误");
            modelAndView.setViewName("register");
            return modelAndView;
        }
        String encodePassword = passwordEncoder.encode(password);
        //注册成功后，添加用户表和用户状态表
        String userName = RandomString.make(10)+new Random().nextInt(100);
        userMapper.insertUser(email,encodePassword,userName);
        Integer i = userMapper.selectUserIdByEmail(email);
        userMapper.insertUserStatus(i);
        modelAndView.addObject("message","注册成功，请登录");
        modelAndView.setViewName("login");
        return modelAndView;
    }

    @Override
    public Integer selectUserIdByEmail(String email) {
        return userMapper.selectUserIdByEmail(email);
    }



    /*
    *根据邮箱更新密码
    * @param email 邮箱
    * @param code 验证码
    * @param newPassword 新密码
    * @return
    * */
    @Override
    public ModelAndView updatePassword(String email, String code , String newPassword,HttpSession session) {
        ModelAndView mv = new ModelAndView();

        //邮箱不存在
        if(!userExistByEmail(email)){
            mv.addObject("message","邮箱不存在");
            mv.setViewName("login");
            return mv;
        }
        //验证码错误
        if(!verificationCodeService.verifyVerificationCode(session,code)){
           mv.addObject("message","验证码错误");
           mv.setViewName("login");
           return mv;
        }
        //密码格式错误
        if(!ValidationUtil.isValidPassword(newPassword)){
            mv.addObject("message","密码格式错误");
            mv.setViewName("login");
            return mv;
        }
        //密码更新成功
        String encodePassword = passwordEncoder.encode(newPassword);
        if(userMapper.updatePassword(email,encodePassword)){
            mv.addObject("message","设置成功");
            mv.setViewName("login");
        }
        return mv;
    }

    @Override
    public Result updatePassword1(String email, String code, String newPassword, HttpSession session) {
        Result result = new Result();
        //邮箱不存在
        if (!userExistByEmail(email)) {
            result.setMessage("邮箱不存在");
            result.setCode(400);
            return result;
        }
        //验证码错误
        if (!verificationCodeService.verifyVerificationCode(session, code)) {
            result.setCode(400);
            result.setMessage("验证码错误");
            return result;
        }
        //密码格式错误
        if (!ValidationUtil.isValidPassword(newPassword)) {
            result.setCode(400);
            result.setMessage("密码格式错误");
            return result;
        }
        //密码更新成功
        String encodePassword = passwordEncoder.encode(newPassword);
        userMapper.updatePassword(email, encodePassword);
        result.setCode(200);
        result.setMessage("修改成功");
        return result;
    }


    /*
    * 根据email判断用户是否存在
    * */
    @Override
    public boolean userExistByEmail(String email) {
        Integer i = userMapper.selectUserIdByEmail(email);
        return i != null;
    }
    /*public ModelAndView registerMember(
            int userId,
            int memberStatus
    ) {
        ModelAndView mav = new ModelAndView("personal_page");
        // 参数校验
        if (userId <= 0) {
            mav.addObject("error", "用户ID不存在");
            mav.addObject("status", "fail");
            return mav;
        }
        if (memberStatus != 0 && memberStatus != 1 && memberStatus != 2) {
            mav.addObject("error", "会员等级只能是0、1、2");
            mav.addObject("status", "fail");
            return mav;
        }
        User user = userMapper.selectUserByUserId(userId);
        if (user==null){
            mav.addObject("error", "用户不存在");
            mav.addObject("status", "fail");
            return mav;
        }
            // 调用DAO层执行注册逻辑（返回受影响行数）
            int rowsAffected = userMapper.registerMember(userId, memberStatus);

            if (rowsAffected > 0) {
                // 注册成功
                mav.addObject("message", "会员注册成功");
                mav.addObject("status", "success");
                mav.addObject("memberStatus", memberStatus);

                // 查询会员信息用于页面展示
                mav.addObject("user", user);
            } else {
                // 注册失败
                mav.addObject("error", "注册失败，请重试");
                mav.addObject("status", "fail");
            }
        return mav;
    }*/

    public ResponseEntity<UserVo> updateUser(UserVo user, HttpSession session) throws Exception {
         ResponseEntity<UserVo> responseEntity = new ResponseEntity<>(user, HttpStatus.OK);
         User userInfo = (User)session.getAttribute("userInfo");
         String avatar = user.getAvatar();
         log.info("更新用户信息,用户名为:{}",user.toString());

        if(!avatar.contains("http")){
             avatar = minioService.uploadImage(avatar);
        }

        List<String> names = userMapper.selectAllName();
        names.remove(userInfo.getUserName());
        if(user.getUserName().length()>20 || user.getUserName().trim().isEmpty()){
            responseEntity = new ResponseEntity<>(user, HttpStatus.BAD_REQUEST);
            return responseEntity;
        }
        if(names.contains(user.getUserName())){
            responseEntity = new ResponseEntity<>(user, HttpStatus.BAD_REQUEST);
            return responseEntity;
        }
        if(user.getIntroduction()!=null && !user.getIntroduction().equals("")){
            userInfo.setAddress(user.getAddress());
        }
        if(user.getAddress()!=null && !user.getAddress().equals("")){
            userInfo.setAddress(user.getAddress());
        }
        if(user.getUserName()!=null&&!user.getUserName().isEmpty()){
            userInfo.setUserName(user.getUserName());
        }
        userInfo.setGender(user.getGender());
        session.removeAttribute("userInfo");
        session.setAttribute("userInfo",userInfo);
        userMapper.updateUserByUserId(userInfo.getUserId(),
                                      userInfo.getUserName(), userInfo.getGender(),
                                      userInfo.getAddress(), userInfo.getIntroduction(),
              avatar);

        return responseEntity;
    }

    @Override
    public Result<Object> applyForVerification(HttpSession session, String applyInformation) {
        User userInfo = (User)session.getAttribute("userInfo");
        Integer userId = userInfo.getUserId();
        if(applyInformation==null||applyInformation.length()==0){
            return Result.error("请输入认证信息");
        }
        if(userMapper.getVerificationRequestId(userId)==null){
            return Result.error("您已经提交过认证申请");
        }
        userMapper.insertVerificationRequest(userId,applyInformation);
        return Result.success("申请成功");
    }



    @Override
    public String redirectToPersonalPage(HttpSession session, RedirectAttributes redirectAttributes,Model model) {
        User useInfo =(User) session.getAttribute("userInfo");
        Map<String,Object> param = new HashMap<>();
        log.info("useInfo:{}",useInfo);
        log.info("param:{}",useInfo.getUserId());

        param.put("userId",useInfo.getUserId());
        useInfo = userMapper.selectUserByUserIdOrEmail(param);
        //粉丝和关注数量
        Integer followerCount = userMapper.countFollower(useInfo.getUserId());
        Integer followedCount = userMapper.countFollowed(useInfo.getUserId());
        useInfo.setFollowerCount(followerCount);
        useInfo.setLikeCount(followedCount);
        if(session.getAttribute("userInfo")==null){
            redirectAttributes.addFlashAttribute("message","请先登录");
            return "redirect:/user/login";
        }
        List<PostDTO> posts = newsMapper.selectPostByPostTypeAndUserId(useInfo.getUserId(),1,-1);
        model.addAttribute("posts",posts);
        model.addAttribute("userInfo",useInfo);
        return "personal_page";
    }

    @Override
    public String redirectToMainPage(HttpSession session, Model model) {
        User userInfo = (User) session.getAttribute("userInfo");
        log.info("userInfo:{}",userInfo);
        //渲染post
        List<PostDTO> posts = newsMapper.selectPostByPageAndTagId(0, 10, 1);
        //格式化时
        posts.forEach(post->{
            String createdTime = FormatTime.formatTimeDifference(post.getTime());
            post.setCreatedTime(createdTime);
        });
        //每日热搜的post
        List<HotSearch> todayHotSearch = newsMapper.selectTodayHotSearch(0,5);
        //总热搜的post
        List<HotSearch> totalHotSearch = newsMapper.selectHotSearch();
        model.addAttribute("posts",posts);
        model.addAttribute("userInfo",userInfo);
        model.addAttribute("todayHotSearch",todayHotSearch);
        model.addAttribute("totalHotSearch",totalHotSearch);
        return "recommend-content";
    }

    @Override
    public Result<Map<String ,Object>> selectPostByPostTypeAndUserId(Integer userId, Integer categoryId, Integer pageNum, HttpSession session) {
        Result<Map<String , Object>> result = new Result<>();
        Map<String ,Object> response = new HashMap<>();
        //判断一下是查询自己的还是他人的
        if(userId == 0){
            User userInfo = (User)session.getAttribute("userInfo");
            if(userInfo == null){
                result.setMessage("请先登录");
                return result;
            }
            userId = userInfo.getUserId();
        }
        //处理不合理数剧
        if(pageNum<=0){
            pageNum = 1;
        }
        int startIndex = (pageNum-1)*10;

        Integer totalCount = newsMapper.selectTotalCountByUserIdAndCategoryId(userId , categoryId,0,1);
        boolean hasMore = (startIndex+10)< totalCount;
        if(totalCount ==0 ){
            response.put("hasMore",hasMore);
            result.setMessage("没有更多的文章了");
            return result;
        }
        List<PostDTO> posts = newsMapper.selectPostByPostTypeAndUserId(userId, categoryId ,startIndex);
        posts.forEach(post -> {
            String createdTime = FormatTime.formatTimeDifference(post.getTime());
            post.setCreatedTime(createdTime);
        });
        response.put("posts",posts);
        response.put("hasMore",hasMore);
        response.put("totalCount",totalCount);
        result.setData(response);
        result.setMessage("success");
        result.setCode(200);
        return result;
    }

    @Override
    public Result<Map<String ,Object>> getBookMarkPostByUserId(int userId,Integer pageNum,HttpSession session) {
        Result<Map<String , Object>> result = new Result<>();
        Map<String ,Object> response = new HashMap<>();
        if(pageNum==null || pageNum<=0){
            pageNum=1;
        }
        int startIndex = (pageNum-1)*10;
        //收藏数量
        if(userId == 0){
            User userInfo = (User)session.getAttribute("userInfo");
            if(userInfo == null){
                result.setMessage("请先登录");
                return result;
            }
            userId = userInfo.getUserId();
        }
        List<PostDTO> posts = newsMapper.selectPostByBookmarkId(userId, startIndex);
        //格式化时间
        posts.forEach(post -> {
            String createdTime = FormatTime.formatTimeDifference(post.getTime());
            post.setCreatedTime(createdTime);
        });
        Integer totalCount = newsMapper.totalCountByBookmarkId(userId);
        boolean hasMore = (startIndex+10)< totalCount;
        if(totalCount ==0 ){
            response.put("hasMore",hasMore);
            result.setMessage("没有更多的文章了");
            return result;
        }
        response.put("posts",posts);
        response.put("hasMore",hasMore);
        response.put("totalCount",totalCount);
        result.setData(response);
        result.setMessage("success");
        result.setCode(200);
        return result;
    }

    @Override
    public Result<Object> setNewPassword(String email, String codeString, String newPassword,HttpSession session) {
        Result<Object> result = new Result<>();
        log.info("code:{}"+session.getAttribute("code"));
        log.info("time:{}"+session.getAttribute("createdTime"));
        //验证码错误
        if(!verificationCodeService.verifyVerificationCode(session,codeString)){
            result.setCode(400);
            result.setMessage("验证码错误");
            log.info("code:{}"+"yancuo");
            return result;
        }
        if(!ValidationUtil.isValidPassword(newPassword)){
            result.setCode(400);
            result.setMessage("密码格式错误");
            return result;
        }
        if(!userExistByEmail(email)){
            result.setCode(400);
            result.setMessage("邮箱不存在");
            return result;
        }
        String encodePassword = passwordEncoder.encode(newPassword);
        userMapper.updatePassword(email,encodePassword);
        result.setCode(200);
        result.setMessage("修改成功");
        return result;
    }

    @Override
    public Result<List<HotSearch>> getTodayHotPost(Integer startPage) {
        Result<List<HotSearch>> result = new Result<>();
        if(startPage<=0){
            result.setCode(400);
            result.setMessage("页码错误");
            return result;
        }
        Integer startIndex = (startPage-1)*5;
        List<HotSearch> hotSearches = newsMapper.selectTodayHotSearch(startIndex, 5);
        if(hotSearches==null){
            result.setCode(400);
            result.setMessage("没有更多的文章了");
            return result;
        }
        result.setCode(200);
        result.setMessage("success");
        result.setData(hotSearches);
        return result;


    }

    @Override
    public Result<Map<String, Object>> selectDraftPostByPage(Integer pageNum, HttpSession session) {
        Result<Map<String, Object>> result = new Result<>();
        Map<String, Object> response = new HashMap<>();
        //处理页码
        if (pageNum == null || pageNum <= 0) {
            pageNum = 1;
        }
        //处理起始索引
        Integer startIndex = (pageNum - 1) * 10;

        User userInfo = (User) session.getAttribute("userInfo");
        if (userInfo == null) {
            result.setCode(400);
            result.setMessage("请先登录");
            return result;
        }
        Integer userId = userInfo.getUserId();
        //查询草稿箱
        List<PostDTO> posts = newsMapper.selectDraftPostByPage(startIndex, userId);
        posts.forEach(post -> {
            String createdTime = FormatTime.formatTimeDifference(post.getTime());
            post.setCreatedTime(createdTime);
        });
       //判断是否还有更多
        Integer totalCount = newsMapper.selectDraftPostCount(userId);
        if (totalCount == 0) {
            response.put("hasMore", false);
            result.setMessage("没有草稿");
            return result;
        }
        boolean hasMore = (startIndex + 10) < totalCount;

        response.put("posts", posts);
        response.put("hasMore", hasMore);
        response.put("totalCount", totalCount);
        result.setData(response);
        return result;


    }

    /*public Result<User> registerMember(@RequestBody User request) {
        // 参数校验
        if ( request.getUserId() <= 0) {
            return Result.badRequest("用户ID不能为空且必须大于0");
        }

        int memberStatus = request.getMemberStatus();
        if (memberStatus != 0 && memberStatus != 1 && memberStatus != 2) {
            return Result.badRequest("会员等级只能是0、1、2");
        }

        // 查询用户
        User user = userMapper.selectUserByUserId(request.getUserId());
        if (user == null) {
            return Result.fail("用户不存在");
        }

        // 调用DAO层执行注册逻辑
        int rowsAffected = userMapper.registerMember(request.getUserId(), memberStatus);

        if (rowsAffected > 0) {
            // 更新用户对象的会员状态
            user.setMemberStatus(memberStatus);
            return Result.success(user, "会员注册成功");
        } else {
            return Result.error("注册失败，请重试");
        }
    }
*/

}
